iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
生成式 AI

AI 產品與架構設計之旅:從 0 到 1,再到 Day 2系列 第 19

Day 19: 一鍵直達 AI 大腦 - 在回覆中嵌入 Trace Link

  • 分享至 

  • xImage
  •  

嗨大家,我是 Debuguy。

前幾天我們把 Langfuse 整合進來了,現在可以看到完整的 trace 資料。但有個問題:

「Bot 回覆了一個奇怪的答案,我想看看執行過程...但要怎麼快速找到對應的 trace?」

想像一下,你的 ChatBot 一天處理幾百個對話,每個對話可能有好幾輪,你要在 Langfuse 的一堆 trace 裡找到「剛剛那個奇怪回覆」...

解決方案:每個回覆都帶上 Trace Link

最直觀的解法就是:每次 Bot 回覆時,順便把這次執行的 trace link 也附上。

這樣一來:

  • 使用者看到奇怪回覆時,直接點 link 就能看 trace
  • 開發者可以秒速 debug,不用大海撈針
  • QA 測試時可以直接檢查 AI 的思考過程

實際實作過程

Step 1: GenKit Flow 回傳 TraceId

首先要讓 GenKit service 把 traceId 回傳出來:

// GenKit/src/index.ts
const chatFlow = ai.defineFlow({
  // ... 原本的處理邏輯
},
async ({ messages }, { sendChunk, trace }) => {
  // ... 原本的處理邏輯

  return {
    text: result.text,
    traceId: trace.traceId, // 這裡是關鍵!
    usage: {
      inputTokens,
      thoughtsTokens,
      outputTokens,
    },
  };
});

注意到 async ({ messages }, { sendChunk, trace }) 這個簽名,GenKit 會自動把當前的 trace 物件傳進來,我們就能拿到 trace.traceId

Step 2: Slack App 的完整實作

看我們實際的 Slack App 實作,比我原本想像的更完整:

// SlackBolt/src/index.ts
app.event('app_mention', async ({ event, say, client }) => {
  // ... 原本的處理邏輯

  try {
    // ... 原本的處理邏輯
    await say({
      text: response.text,
      blocks: [
        // ... 原本的處理邏輯
        // 這裡是 trace link 的關鍵部分!
        {
          "type": "section",
          "text": {
            "type": "mrkdwn",
            "text": `<${process.env['LANGFUSE_URL']}/project/${process.env['LANGFUSE_PROJECT_ID']}/traces?peek=${response.traceId}|${response.traceId}>`
          }
        }
      ],
      thread_ts: event.thread_ts || event.ts
    });
  } catch (error) {
    console.error('Error processing app mention:', error);
    // 錯誤處理...
  }
});

URL 分析

這是 langfuse 的 url

http://localhost:3000/project/cmg84b8bg0006q007k2hg2fg9/traces?peek=4f471f2f1597f10cfed9fc0c6120bd43

因此我們可以拆解為兩部分

  1. LANGFUSE_URL: http://localhost:3000
  2. LANGFUSE_PROJECT_ID: cmg84b8bg0006q007k2hg2fg9
  3. Trace Id: 4f471f2f1597f10cfed9fc0c6120bd43

接著使用 Slack 的 URL 格式組合

`<${process.env['LANGFUSE_URL']}/project/${process.env['LANGFUSE_PROJECT_ID']}/traces?peek=${response.traceId}|${response.traceId}>`

實際效果

現在當 Bot 處理請求時:

  1. 先顯示 "Thinking..."
  2. 即時更新推理過程(如果模型有 reasoning)
  3. 最終回覆包含
    • 主要回答內容
    • 詳細的 token 使用統計
    • 可點擊的 trace link

點擊 trace link 就會直接跳到 Langfuse 對應的 trace 頁面,可以看到:

  • 完整的 LLM 呼叫過程
  • MCP tool 的使用記錄
  • 每個步驟的執行時間
  • Token 使用詳情

這樣做的好處

1. Debug 效率爆增

「這個回覆怎麼這麼奇怪?」
點擊 trace link
「原來是 MCP tool 回傳了錯誤資料...」

再也不用在一堆 trace 裡找了。

2. 透明度大幅提升

使用者可以看到 AI 的完整思考過程:

「為什麼 AI 建議我這麼做?」
點擊 trace link 看 reasoning 和 tool calls
「原來它查了這些資料,考慮了這些因素,合理。」

3. 測試變得更容易

QA 測試時:

  • 不用額外開工具
  • 直接在 Slack 裡檢查 AI 行為
  • 可以驗證 tool 呼叫是否正確

技術亮點

OpenTelemetry 的威力

這個功能之所以這麼容易實作,是因為 GenKit 基於 OpenTelemetry。每個 flow 執行都會自動產生一個 trace,我們只要把 traceId 傳出來就行了。

小結

這次的改動帶來的實用價值:

  • ✅ 每個回覆都有對應的 trace link
  • ✅ Debug 效率大幅提升
  • ✅ AI 思考過程完全透明
  • ✅ 測試流程更順暢

這就是選擇好工具組合的威力 — GenKit + OpenTelemetry + Langfuse 讓我們用很少的程式碼,達到企業級的可觀測性。

當你能即時看到 AI 的「大腦」在想什麼,並且一鍵直達詳細的執行記錄時,開發和除錯就變得輕鬆很多。


完整的原始碼在這裡,可以看到實際的 trace 整合實作!


AI 的發展變化很快,目前這個想法以及專案也還在實驗中。但也許透過這個過程大家可以有一些經驗和想法互相交流,歡迎大家追蹤這個系列。

也歡迎追蹤我的 Threads @debuguy.dev


上一篇
Day 18:Prompt 也要模組化?談談 Partial Prompts 的妙用
下一篇
Day 20: 當 AI 也需要「翻譯蒟蒻」- 從提示詞到製作工具
系列文
AI 產品與架構設計之旅:從 0 到 1,再到 Day 224
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言